package net.tv90.bfmccore.game.commander;

import net.tv90.bfmccore.event.PlayerCountryChangeEvent;
import net.tv90.bfmccore.game.GameBase;
import net.tv90.bfmccore.game.GameManager;
import org.bitterorange.flansmodslain.FlansModAPI;
import org.bitterorange.flansmodslain.FlansModSlain;
import org.bitterorange.flansmodslain.actions.Money;
import org.bitterorange.flansmodslain.actions.Point;
import org.bitterorange.flansmodslain.models.PlayerSlainEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerQuitEvent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class AbstractCommanderSystem implements ICommanderSystem {

    public static String firstFactionCommander = "战场自动指挥系统";

    public static String secondFactionCommander = "战场自动指挥系统";

    public static Player firstFactionHighValueTarget = null;

    public static Player secondFactionHighValueTarget = null;
    protected int firstFactionHighValueTargetMarkTime = 0;
    protected int secondFactionHighValueTargetMarkTime = 0;

    protected long firstFactionTickTime = 0;
    protected long secondFactionTickTime = 0;

    protected boolean firstFactionCommanderOnline = false;
    protected boolean secondFactionCommanderOnline = false;

    private boolean isFirstFactionCommanderInit = false;
    private boolean isSecondFactionCommanderInit = false;

    public AbstractCommanderSystem() {
    }

    // 初始化自动指挥系统间隔, 单位秒
    public long getFIRST_FACTION_AUTO_COMMANDER_INIT_TICK() {
        return 60;
    }

    // 初始化自动指挥系统间隔, 单位秒
    public long getSECOND_FACTION_AUTO_COMMANDER_INIT_TICK() {
        return 80;
    }

    // 当不存在指挥官时，应用自动指挥系统间隔, 单位秒
    public long getAUTO_COMMANDER_TICK() {
        return 50;
    }

    // 高价值目标刷新间隔, 单位秒
    public long getHIGH_VALUE_TARGET_DELAY() {
        return 150;
    }

    // 高价值目标悬赏时间, 单位秒
    public long getHIGH_VALUE_TARGET_MARK_TIME() {
        return 30;
    }

    /**
     * 判断第一阵营是否有自动指挥官
     *
     * @return
     */
    protected boolean isFirstFactionAutoCommander() {
        return firstFactionCommanderOnline && firstFactionCommander.equals("战场自动指挥系统");
    }

    /**
     * 判断第二阵营是否有自动指挥官
     *
     * @return
     */
    protected boolean isSecondFactionAutoCommander() {
        return secondFactionCommanderOnline && secondFactionCommander.equals("战场自动指挥系统");
    }

    /**
     * 判断第一阵营是否有玩家指挥官
     *
     * @return
     */
    protected boolean isFirstFactionPlayerCommander() {
        return firstFactionCommanderOnline && !firstFactionCommander.equals("战场自动指挥系统");
    }

    /**
     * 判断第二阵营是否有玩家指挥官
     *
     * @return
     */
    protected boolean isSecondFactionPlayerCommander() {
        return secondFactionCommanderOnline && !secondFactionCommander.equals("战场自动指挥系统");
    }

    /**
     * 初始化自动指挥系统
     */
    public void initFirstFactionCommander() {
        broadcastFirstFactionCommander();
        firstFactionCommanderOnline = true;
        isFirstFactionCommanderInit = true;
    }

    /**
     * 初始化自动指挥系统
     */
    public void initSecondFactionCommander() {
        broadcastSecondFactionCommander();
        secondFactionCommanderOnline = true;
        isSecondFactionCommanderInit = true;
    }

    /**
     * 设置第一阵营指挥官
     *
     * @param player 玩家
     */
    public void setFirstFactionCommander(Player player) {
        firstFactionCommander = player.getName();
        broadcastFirstFactionCommander();
        firstFactionCommanderOnline = true;
    }

    /**
     * 设置第二阵营指挥官
     *
     * @param player 玩家
     */
    public void setSecondFactionCommander(Player player) {
        secondFactionCommander = player.getName();
        broadcastSecondFactionCommander();
        secondFactionCommanderOnline = true;
    }

    /**
     * 取消第一阵营指挥官
     */
    public void unsetFirstFactionCommander() {
        firstFactionCommander = "战场自动指挥系统";
        firstFactionCommanderOnline = false;
    }

    /**
     * 取消第二阵营指挥官
     */
    public void unsetSecondFactionCommander() {
        secondFactionCommander = "战场自动指挥系统";
        secondFactionCommanderOnline = false;
    }

    protected boolean autoSetFirstFactionHighValueTarget() {
        int maxLinkedKillCount = 0;
        Player highValueTarget = null;
        for (Player player : GameBase.firstFactionList) {
            if (FlansModSlain.getLinkedKillCountOf(player) > maxLinkedKillCount) {
                maxLinkedKillCount = FlansModSlain.getLinkedKillCountOf(player);
                highValueTarget = player;
            }
        }
        firstFactionHighValueTarget = highValueTarget;
        System.out.println(GameManager.getInstance().currentGame.firstFactionName + "高价值目标刷新" + firstFactionHighValueTarget);
        return highValueTarget != null;
    }

    protected boolean autoSetSecondFactionHighValueTarget() {
        int maxLinkedKillCount = 0;
        Player highValueTarget = null;
        for (Player player : GameBase.secondFactionList) {
            if (FlansModSlain.getLinkedKillCountOf(player) > maxLinkedKillCount) {
                maxLinkedKillCount = FlansModSlain.getLinkedKillCountOf(player);
                highValueTarget = player;
            }
        }
        secondFactionHighValueTarget = highValueTarget;
        System.out.println(GameManager.getInstance().currentGame.secondFactionName + "高价值目标刷新" + secondFactionHighValueTarget);
        return highValueTarget != null;
    }

    /**
     * 取消第一阵营高价值目标
     */
    public void unsetFirstFactionHighValueTarget() {
        firstFactionHighValueTarget = null;
    }

    /**
     * 取消第二阵营高价值目标
     */
    public void unsetSecondFactionHighValueTarget() {
        secondFactionHighValueTarget = null;
    }

    private void broadcastFirstFactionCommander() {
        Bukkit.broadcastMessage("§e[管理员]" + firstFactionCommander + "已成为" + GameManager.getInstance().currentGame.firstFactionName + "指挥官");
        for (Player p : GameBase.firstFactionList) {
            noticeCommanderOnline(p);
        }
        for (Player p : GameBase.secondFactionList) {
            noticeEnemyCommanderOnline(p);
        }
    }

    private void broadcastSecondFactionCommander() {
        Bukkit.broadcastMessage("§e[管理员]" + secondFactionCommander + "已成为" + GameManager.getInstance().currentGame.secondFactionName + "指挥官");
        for (Player p : GameBase.secondFactionList) {
            noticeCommanderOnline(p);
        }
        for (Player p : GameBase.firstFactionList) {
            noticeEnemyCommanderOnline(p);
        }
    }

    private void broadcastFirstFactionHighValueTarget() {
        if (firstFactionHighValueTarget == null) return;
        for (Player p : GameBase.firstFactionList) {
            p.sendMessage("§e[指挥官]" + GameManager.getInstance().currentGame.secondFactionName + "指挥官"
                    + secondFactionCommander + "将己方玩家"
                    + firstFactionHighValueTarget.getName() + "标记为高价值目标，注意保护!");
        }
        for (Player p : GameBase.secondFactionList) {
            p.sendMessage("§e[指挥官]" + GameManager.getInstance().currentGame.secondFactionName + "指挥官"
                    + secondFactionCommander + "将对方玩家"
                    + firstFactionHighValueTarget.getName() + "标记为高价值目标，在" + getHIGH_VALUE_TARGET_MARK_TIME() + "s内将其击杀可获得丰厚奖励");
        }
        Player p = GameBase.secondFactionList.isEmpty() ? null : (Player) GameBase.secondFactionList.toArray()[0];
        if (p != null) {
            List<Entity> list = new ArrayList<>();
            list.add(firstFactionHighValueTarget);
            if(firstFactionHighValueTarget.getVehicle() != null) {
                list.add(firstFactionHighValueTarget.getVehicle());
            }
            FlansModAPI.markEntity(p, 10, list);
        }
    }

    private void broadcastSecondFactionHighValueTarget() {
        if (secondFactionHighValueTarget == null) return;
        for (Player p : GameBase.secondFactionList) {
            p.sendMessage("§e[指挥官]" + GameManager.getInstance().currentGame.firstFactionName + "指挥官"
                    + firstFactionCommander + "将己方玩家"
                    + secondFactionHighValueTarget.getName() + "标记为高价值目标，注意保护!");
        }
        for (Player p : GameBase.firstFactionList) {
            p.sendMessage("§e[指挥官]" + GameManager.getInstance().currentGame.firstFactionName + "指挥官"
                    + firstFactionCommander + "将对方玩家"
                    + secondFactionHighValueTarget.getName() + "标记为高价值目标，在" + getHIGH_VALUE_TARGET_MARK_TIME() + "s内将其击杀可获得丰厚奖励");
        }
        Player p = GameBase.firstFactionList.isEmpty() ? null : (Player) GameBase.firstFactionList.toArray()[0];
        if (p != null) {
            List<Entity> list = new ArrayList<>();
            list.add(secondFactionHighValueTarget);
            if(secondFactionHighValueTarget.getVehicle() != null) {
                list.add(secondFactionHighValueTarget.getVehicle());
            }
            FlansModAPI.markEntity(p, 10, list);
        }
    }

    private void noticeCommanderOnline(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 己方指挥官上线");
    }

    private void noticeCommanderOffline(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 己方指挥官下线");
    }

    private void noticeEnemyCommanderOnline(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 敌方指挥官上线");
    }

    private void noticeEnemyCommanderOffline(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 敌方指挥官下线");
    }

    private void noticeHighValueTarget(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 已指定敌方高价值目标");
    }

    private void noticeMarkedHighValueTarget(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 敌方已悬赏高价值目标");
    }

    private void noticeUnsetHighValueTarget(Player p) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "title " + p.getName() + " title 高价值目标已丢失");
    }

    /**
     * 由第二阵营自动标记第一阵营高价值目标
     */
    public void autoPerformFirstFactionHighValueTarget() {
        if (firstFactionHighValueTarget == null) {
            if (autoSetFirstFactionHighValueTarget()) {
                broadcastFirstFactionHighValueTarget();
                // 通知第二阵营玩家
                for (Player p : GameBase.secondFactionList) {
                    noticeHighValueTarget(p);
                }
                for (Player p : GameBase.firstFactionList) {
                    noticeMarkedHighValueTarget(p);
                }
            }
        }
    }

    /**
     * 由第一阵营自动标记第二阵营高价值目标
     */
    public void autoPerformSecondFactionHighValueTarget() {
        if (secondFactionHighValueTarget == null) {
            if (autoSetSecondFactionHighValueTarget()) {
                broadcastSecondFactionHighValueTarget();
                // 通知第一阵营玩家
                for (Player p : GameBase.firstFactionList) {
                    noticeHighValueTarget(p);
                }
                for (Player p : GameBase.secondFactionList) {
                    noticeMarkedHighValueTarget(p);
                }
            }
        }
    }

    /**
     * 由第二阵营自动取消第一阵营高价值目标
     */
    public void autoUnsetFirstFactionHighValueTarget() {
        if (isFirstFactionHighValueTargetExisted()) {
            for (Player p : GameBase.secondFactionList) {
                noticeUnsetHighValueTarget(p);
            }
        }
        unsetFirstFactionHighValueTarget();
    }

    /**
     * 由第一阵营自动取消第二阵营高价值目标
     */
    public void autoUnsetSecondFactionHighValueTarget() {
        if (isSecondFactionHighValueTargetExisted()) {
            for (Player p : GameBase.firstFactionList) {
                noticeUnsetHighValueTarget(p);
            }
        }
        unsetSecondFactionHighValueTarget();
    }

    /**
     * 判断第一阵营高价值目标是否存在
     *
     * @return 是否存在
     */
    public boolean isFirstFactionHighValueTargetExisted() {
        if (firstFactionHighValueTarget == null) return false;
        else
            return firstFactionHighValueTarget.isOnline() && GameBase.firstFactionList.contains(firstFactionHighValueTarget);
    }

    /**
     * 判断第二阵营高价值目标是否存在
     *
     * @return 是否存在
     */
    public boolean isSecondFactionHighValueTargetExisted() {
        if (secondFactionHighValueTarget == null) return false;
        else
            return secondFactionHighValueTarget.isOnline() && GameBase.secondFactionList.contains(secondFactionHighValueTarget);
    }

    /**
     * 玩家被击杀时触发
     */
    public void onPlayerSlain(PlayerSlainEvent e) {

        if (!e.isKilledAI() && !e.isKillerAI()) {
            Player killed = e.getPlayerKilled();
            Player killer = e.getPlayerKiller();
            String weapon;
            if (e.isVehicleKill()) {
                weapon = FlansModAPI.getPlayerVehicle(e.getPlayerKiller());
            } else {
                weapon = FlansModAPI.nameOfWeapon(e.getOriginalMaterial());
            }

            if (AbstractCommanderSystem.firstFactionHighValueTarget != null && killed == AbstractCommanderSystem.firstFactionHighValueTarget) {
                Bukkit.broadcastMessage("§e[指挥官]" + killer.getName() + "使用" + weapon + "击杀了高价值目标" + killed.getName() + "获得3倍奖励");
                killer.sendMessage("§e[悬赏击杀]你额外获得15军衔和30游戏币");
                Point.add(killer, 15);
                Money.give(killer, 30);
                unsetFirstFactionHighValueTarget();
            }
            if (AbstractCommanderSystem.secondFactionHighValueTarget != null && killed == AbstractCommanderSystem.secondFactionHighValueTarget) {
                Bukkit.broadcastMessage("§e[指挥官]" + killer.getName() + "使用" + weapon + "击杀了高价值目标" + killed.getName() + "获得3倍奖励");
                killer.sendMessage("§e[悬赏击杀]你额外获得15军衔和30游戏币");
                Point.add(killer, 15);
                Money.give(killer, 30);
                unsetSecondFactionHighValueTarget();
            }
        }

    }

    /**
     * 玩家国籍变更时触发
     *
     * @param e
     */
    public void onPlayerCountryChange(PlayerCountryChangeEvent e) {
        Player p = e.getPlayer();
        if (AbstractCommanderSystem.firstFactionHighValueTarget != null && p == AbstractCommanderSystem.firstFactionHighValueTarget) {
            unsetFirstFactionHighValueTarget();
        }
        if (AbstractCommanderSystem.secondFactionHighValueTarget != null && p == AbstractCommanderSystem.secondFactionHighValueTarget) {
            unsetSecondFactionHighValueTarget();
        }
    }

    /**
     * 玩家退出时触发
     *
     * @param e
     */
    public void onPlayerQuit(PlayerQuitEvent e) {
        Player p = e.getPlayer();
        if (AbstractCommanderSystem.firstFactionHighValueTarget != null && p == AbstractCommanderSystem.firstFactionHighValueTarget) {
            unsetFirstFactionHighValueTarget();
        }
        if (AbstractCommanderSystem.secondFactionHighValueTarget != null && p == AbstractCommanderSystem.secondFactionHighValueTarget) {
            unsetSecondFactionHighValueTarget();
        }
    }

    @Override
    public void tick(GameBase gameBase) {

        //战局开始初始化指挥系统
        if (!isFirstFactionCommanderInit && GameBase.frame == getFIRST_FACTION_AUTO_COMMANDER_INIT_TICK()) {
            initFirstFactionCommander();
        }
        if (!isSecondFactionCommanderInit && GameBase.frame == getSECOND_FACTION_AUTO_COMMANDER_INIT_TICK()) {
            initSecondFactionCommander();
        }

        // 当指挥官不存在时，自动应用指挥系统
        if (isFirstFactionCommanderInit && GameBase.frame % getAUTO_COMMANDER_TICK() == 0 && !isFirstFactionPlayerCommander() && !isFirstFactionAutoCommander()) {
            initFirstFactionCommander();
        }
        if (isSecondFactionCommanderInit && GameBase.frame % getAUTO_COMMANDER_TICK() == 0 && !isSecondFactionPlayerCommander() && !isSecondFactionAutoCommander()) {
            initSecondFactionCommander();
        }

        if (firstFactionCommanderOnline) {
            firstFactionTickTime++;
        } else {
            firstFactionTickTime = 0;
        }

        if (secondFactionCommanderOnline) {
            secondFactionTickTime++;
        } else {
            secondFactionTickTime = 0;
        }
    }

    public enum CommanderState {

        COMMANDER_UNINITIALIZED {

        },

        NO_COMMANDER {

        },

        PLAYER_COMMANDER {

        },

        AUTO_COMMANDER {

        };

    }

}
